/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package net.db.generator;

/**
 *
 * @author abosancic
 */
public class JavaDAOClassWriter extends JavaBaseClassWriter {

    public JavaDAOClassWriter() {
        super();
    }

    @Override
    protected void generateClassName() {
        stringClass.append("public abstract class DAOBase<T, PK extends Serializable> implements IDAOBase<T, PK> {\n\n");
        generateDAOClass();
    }

    //==========================================================================
    // setters and getters
    //==========================================================================
    @Override
    public String getClassName() {
        return "DAOBase";
    }

    protected void generateDAOClass() {

        String daoClass = "    //==========================================================================\n"
                + "    //  property\n"
                + "    //==========================================================================\n"
                + "    protected Class<T> persistentClass = null;\n"
                + "    protected Class[] methodsType = null;\n"
                + "    protected String[] methodsTypeSimpleName = null;\n"
                + "    protected String[] preparedStatementMethodsName = null;\n"
                + "    protected Class[] preparedStatementMethodsType = null;\n"
                + "    protected String[] preparedPrimaryStatementMethodsName = null;\n"
                + "    protected Class[] preparedPrimaryStatementMethodsType = null;\n"
                + "    protected Method [] preparedPrimaryStatment;\n"
                + "    protected Method[] setters = null;\n"
                + "    protected Method[] getters = null;\n"
                + "\n"
                + "    public DAOBase() {\n"
                + "        ParameterizedType genericSuperclass = (ParameterizedType) getClass().getGenericSuperclass();\n"
                + "        this.persistentClass = (Class<T>) genericSuperclass.getActualTypeArguments()[0];\n"
                + "        cashedMethodsType();\n"
                + "        cashedPreparedStatementMethodsName();\n"
                + "        cashedPrimaryPreparedStatementMethodsName();\n"
                + "        cashedMethods();\n"
                + "    }\n"
                + "\n"
                + "    public DAOBase(Class<T> persistentClass) {\n"
                + "        this.persistentClass = persistentClass;\n"
                + "        cashedMethodsType();\n"
                + "        cashedPreparedStatementMethodsName();\n"
                + "        cashedPrimaryPreparedStatementMethodsName();\n"
                + "        cashedMethods();\n"
                + "    }\n"
                + "\n"
                + "    @Override\n"
                + "    public T find(PK id) {\n"
                + "\n"
                + "        Connection dbConnection = null;\n"
                + "        try {\n"
                + "\n"
                + "            PreparedStatement preparedStatement = null;\n"
                + "\n"
                + "            String query = \"SELECT * FROM \" + getTableName()\n"
                + "                    + \" WHERE \" + appendPrimaryKey();\n"
                + "//            System.out.println(\"query: \" + query);\n"
                + "            dbConnection = ConnectionPool.getConnectionPool().checkOut();\n"
                + "            preparedStatement = dbConnection.prepareStatement(query);\n"
                + "\n"
                + "            String keys[] = getPrimaryKeyName();\n"
                + "            int num = keys.length;\n"
                + "            \n"
                + "            if (id instanceof BasePK) {\n"
                + "                int indexPK = 1;\n"
                + "                for (int i = 0; i < num; i++) {\n"
                + "                    Method prepareM = preparedStatement.getClass().getMethod(preparedPrimaryStatementMethodsName[i], int.class, preparedPrimaryStatementMethodsType[i]);\n"
                + "                    Method method = id.getClass().getMethod(ClassGeneratorUtil.humanizeToGetter(keys[i]));\n"
                + "                    prepareM.invoke(preparedStatement, indexPK, method.invoke(id));\n"
                + "                    indexPK++;\n"
                + "                }\n"
                + "            } else {\n"
                + "                Method prepareM = preparedStatement.getClass().getMethod(preparedPrimaryStatementMethodsName[0], int.class, preparedPrimaryStatementMethodsType[0]);\n"
                + "                prepareM.invoke(preparedStatement, 1, id);\n"
                + "            }\n"
                + "            ResultSet res = preparedStatement.executeQuery();\n"
                + "            Object object = persistentClass.newInstance();\n"
                + "\n"
                + "            String fields[] = getColumns();\n"
                + "            num = fields.length;\n"
                + "            while (res.next()) {\n"
                + "                for (int i = 0; i < num; i++) {\n"
                + "                    setters[i].invoke(object, getMapperDB(methodsTypeSimpleName[i], res, fields[i]));\n"
                + "                }\n"
                + "                break;\n"
                + "            }\n"
                + "            //System.out.println(\"\" + object);\n"
                + "            return (T) object;\n"
                + "\n"
                + "        } catch (Exception ex) {\n"
                + "            Logger.getLogger(DAOBase.class.getName()).log(Level.SEVERE, null, ex);\n"
                + "            ex.printStackTrace();\n"
                + "        } finally {\n"
                + "            ConnectionPool.getConnectionPool().checkIn(dbConnection);\n"
                + "        }\n"
                + "\n"
                + "        return null;\n"
                + "    }\n"
                + "\n"
                + "    @Override\n"
                + "    public List<T> findAll() {\n"
                + "\n"
                + "        List<T> items = new ArrayList<T>();\n"
                + "        Connection dbConnection = null;\n"
                + "        try {\n"
                + "\n"
                + "            PreparedStatement preparedStatement = null;\n"
                + "\n"
                + "            String query = \"SELECT * FROM \" + getTableName();\n"
                + "//            System.out.println(\"query: \" + query);           \n"
                + "            dbConnection = ConnectionPool.getConnectionPool().checkOut();\n"
                + "            preparedStatement = dbConnection.prepareStatement(query);\n"
                + "\n"
                + "            ResultSet res = preparedStatement.executeQuery();\n"
                + "\n"
                + "            String[] columns = getColumns();\n"
                + "            int num = columns.length;\n"
                + "\n"
                + "            while (res.next()) {\n"
                + "                Object object = persistentClass.newInstance();\n"
                + "                for (int i = 0; i < num; i++) {\n"
                + "                    setters[i].invoke(object, getMapperDB(methodsTypeSimpleName[i], res, columns[i]));\n"
                + "                }\n"
                + "                items.add((T) object);\n"
                + "            }\n"
                + "\n"
                + "            System.out.println(\"num of items: \" + items.size());\n"
                + "            res.close();\n"
                + "            preparedStatement.close();\n"
                + "\n"
                + "        } catch (Exception ex) {\n"
                + "            Logger.getLogger(DAOBase.class.getName()).log(Level.SEVERE, null, ex);\n"
                + "        } finally {\n"
                + "            ConnectionPool.getConnectionPool().checkIn(dbConnection);\n"
                + "        }\n"
                + "\n"
                + "        return items;\n"
                + "    }\n"
                + "\n"
                + "    /**\n"
                + "     *\n"
                + "     * @param field\n"
                + "     * @param value\n"
                + "     * @return\n"
                + "     */\n"
                + "    protected List<T> findProcessing(String field, Object value) {\n"
                + "\n"
                + "        List<T> items = new ArrayList<T>();\n"
                + "        Connection dbConnection = null;;\n"
                + "        try {\n"
                + "\n"
                + "            PreparedStatement preparedStatement = null;\n"
                + "\n"
                + "            String query = \"SELECT * FROM \" + getTableName()\n"
                + "                    + \" WHERE \" + field + \"=?\";\n"
                + "\n"
                + "            dbConnection = ConnectionPool.getConnectionPool().checkOut();\n"
                + "            preparedStatement = dbConnection.prepareStatement(query);\n"
                + "\n"
                + "            String fields[] = getColumns();\n"
                + "            int num = fields.length;\n"
                + "\n"
                + "            for (int i = 0; i < num; i++) {\n"
                + "                if (field.equals(fields[i])) {\n"
                + "                    Method prepareM = preparedStatement.getClass().getMethod(preparedStatementMethodsName[i], int.class, preparedStatementMethodsType[i]);\n"
                + "                    prepareM.invoke(preparedStatement, 1, value);\n"
                + "                }\n"
                + "            }\n"
                + "\n"
                + "            ResultSet res = preparedStatement.executeQuery();\n"
                + "\n"
                + "            while (res.next()) {\n"
                + "\n"
                + "                T object = persistentClass.newInstance();\n"
                + "\n"
                + "                for (int i = 0; i < num; i++) {\n"
                + "                    setters[i].invoke(object, getMapperDB(methodsTypeSimpleName[i], res, fields[i]));\n"
                + "                }\n"
                + "\n"
                + "                items.add(object);\n"
                + "            }\n"
                + "\n"
                + "            return items;\n"
                + "\n"
                + "        } catch (Exception ex) {\n"
                + "            Logger.getLogger(DAOBase.class.getName()).log(Level.SEVERE, null, ex);\n"
                + "            ex.printStackTrace();\n"
                + "        } finally {\n"
                + "            ConnectionPool.getConnectionPool().checkIn(dbConnection);\n"
                + "        }\n"
                + "\n"
                + "        return items;\n"
                + "    }\n"
                + "\n"
                + "    /**\n"
                + "     *\n"
                + "     * @param range range[0] is current page range[1] is page size\n"
                + "     * @return List<T> items\n"
                + "     */\n"
                + "    public List<T> findRange(int[] range) {\n"
                + "\n"
                + "        List<T> items = new ArrayList<T>();\n"
                + "        Connection dbConnection = null;\n"
                + "        try {\n"
                + "\n"
                + "            PreparedStatement preparedStatement = null;\n"
                + "\n"
                + "            String query = \"SELECT * FROM \" + getTableName() + \" LIMIT \" + range[0] + \", \" + range[1];\n"
                + "            System.out.println(\"query: \" + query);\n"
                + "            dbConnection = ConnectionPool.getConnectionPool().checkOut();\n"
                + "            preparedStatement = dbConnection.prepareStatement(query);\n"
                + "\n"
                + "            ResultSet res = preparedStatement.executeQuery();\n"
                + "\n"
                + "            String[] columns = getColumns();\n"
                + "            int num = columns.length;\n"
                + "\n"
                + "            while (res.next()) {\n"
                + "                Object object = persistentClass.newInstance();\n"
                + "                for (int i = 0; i < num; i++) {\n"
                + "                    setters[i].invoke(object, getMapperDB(methodsTypeSimpleName[i], res, columns[i]));\n"
                + "                }\n"
                + "                items.add((T) object);\n"
                + "            }\n"
                + "\n"
                + "            System.out.println(\"num of items: \" + items.size());\n"
                + "            res.close();\n"
                + "            preparedStatement.close();\n"
                + "\n"
                + "        } catch (Exception ex) {\n"
                + "            Logger.getLogger(DAOBase.class.getName()).log(Level.SEVERE, null, ex);\n"
                + "        } finally {\n"
                + "            ConnectionPool.getConnectionPool().checkIn(dbConnection);\n"
                + "        }\n"
                + "\n"
                + "        return items;\n"
                + "\n"
                + "    }\n"
                + "\n"
                + "    @Override\n"
                + "    public boolean remove(PK id) {\n"
                + "        boolean result = false;\n"
                + "        Connection dbConnection = null;\n"
                + "        try {\n"
                + "            if (id == null) {\n"
                + "                return result;\n"
                + "            }\n"
                + "\n"
                + "            PreparedStatement preparedStatement = null;\n"
                + "            String query = \"DELETE FROM \" + getTableName()\n"
                + "                    + \" WHERE \" + appendPrimaryKey();\n"
                + "//            System.out.println(\"rquery: \" + query);\n"
                + "            dbConnection = ConnectionPool.getConnectionPool().checkOut();\n"
                + "            preparedStatement = dbConnection.prepareStatement(query);\n"
                + "\n"
                + "            String keys[] = getPrimaryKeyName();\n"
                + "            int num = keys.length;\n"
                + "            \n"
                + "            if (id instanceof BasePK) {\n"
                + "                int indexPK = 1;\n"
                + "                for (int i = 0; i < num; i++) {\n"
                + "                    Method prepareM = preparedStatement.getClass().getMethod(preparedPrimaryStatementMethodsName[i], int.class, preparedPrimaryStatementMethodsType[i]);\n"
                + "                    Method method = id.getClass().getMethod(ClassGeneratorUtil.humanizeToGetter(keys[i]));\n"
                + "                    prepareM.invoke(preparedStatement, indexPK, method.invoke(id));\n"
                + "                    indexPK++;\n"
                + "                }\n"
                + "            } else {\n"
                + "                Method prepareM = preparedStatement.getClass().getMethod(preparedPrimaryStatementMethodsName[0], int.class, preparedPrimaryStatementMethodsType[0]);\n"
                + "                prepareM.invoke(preparedStatement, 1, id);\n"
                + "            }\n"
                + "\n"
                + "            result = (preparedStatement.executeUpdate() > 0) ? true : false;\n"
                + "\n"
                + "        } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException | SQLException ex) {\n"
                + "            Logger.getLogger(DAOBase.class.getName()).log(Level.SEVERE, null, ex);\n"
                + "        } finally {\n"
                + "            ConnectionPool.getConnectionPool().checkIn(dbConnection);\n"
                + "        }\n"
                + "        return result;\n"
                + "    }\n"
                + "\n"
                + "    @Override\n"
                + "    public boolean remove(T t) {\n"
                + "        \n"
                + "        boolean result = false;\n"
                + "        Connection dbConnection = null;\n"
                + "        \n"
                + "        try {\n"
                + "\n"
                + "            if (t == null) {\n"
                + "                return result;\n"
                + "            }\n"
                + "            \n"
                + "            PreparedStatement preparedStatement = null;\n"
                + "            String query = \"DELETE FROM \" + getTableName()\n"
                + "                    + \" WHERE \" + appendPrimaryKey();\n"
                + "            //System.out.println(\"rquery: \" + query);\n"
                + "            dbConnection = ConnectionPool.getConnectionPool().checkOut();\n"
                + "            preparedStatement = dbConnection.prepareStatement(query);\n"
                + "\n"
                + "            String keys[] = getPrimaryKeyName();\n"
                + "            int num = keys.length;\n"
                + "            \n"
                + "            String columns[] = getColumns();\n"
                + "            int fileds = columns.length;\n"
                + "            \n"
                + "            int indexPK = 1;\n"
                + "            for (int i = 0; i < num; i++) {\n"
                + "                 for (int j = 0; j < fileds; j++) {\n"
                + "                    if(keys[i].equals(columns[j])){\n"
                + "                        Method prepareM = preparedStatement.getClass().getMethod(preparedStatementMethodsName[j], int.class, preparedStatementMethodsType[j]);\n"
                + "                        prepareM.invoke(preparedStatement, indexPK, getters[j].invoke(t));\n"
                + "                        indexPK++;\n"
                + "                        break;\n"
                + "                    }\n"
                + "                } \n"
                + "            }\n"
                + "\n"
                + "            result = (preparedStatement.executeUpdate() > 0) ? true : false;\n"
                + "\n"
                + "        } catch (Exception ex) {\n"
                + "            Logger.getLogger(DAOBase.class.getName()).log(Level.SEVERE, null, ex);\n"
                + "            Logger.getLogger(t.getClass().getName()).log(Level.SEVERE, null, t);\n"
                + "        }\n"
                + "        return result;\n"
                + "    }\n"
                + "\n"
                + "    protected boolean removeProcessing(String field, Object value) {\n"
                + "\n"
                + "        boolean result = false;\n"
                + "        Connection dbConnection = null;\n"
                + "        try {\n"
                + "\n"
                + "            if (value == null) {\n"
                + "                return result;\n"
                + "            }\n"
                + "\n"
                + "            PreparedStatement preparedStatement = null;\n"
                + "            String query = \"DELETE FROM \" + getTableName()\n"
                + "                    + \" WHERE \" + field + \"=?\";\n"
                + "\n"
                + "            dbConnection = ConnectionPool.getConnectionPool().checkOut();\n"
                + "            preparedStatement = dbConnection.prepareStatement(query);\n"
                + "\n"
                + "            String fields[] = getColumns();\n"
                + "            int num = fields.length;\n"
                + "\n"
                + "            for (int i = 0; i < num; i++) {\n"
                + "                if (field.equals(fields[i])) {\n"
                + "                    java.lang.reflect.Method prepareM = preparedStatement.getClass().getMethod(preparedStatementMethodsName[i], int.class, preparedStatementMethodsType[i]);\n"
                + "                    prepareM.invoke(preparedStatement, 1, value);\n"
                + "                }\n"
                + "            }\n"
                + "\n"
                + "            result = (preparedStatement.executeUpdate() > 0) ? true : false;\n"
                + "\n"
                + "        } catch (IllegalAccessException | IllegalArgumentException | java.lang.reflect.InvocationTargetException | NoSuchMethodException | SecurityException | java.sql.SQLException ex) {\n"
                + "            Logger.getLogger(DAOBase.class.getName()).log(Level.SEVERE, null, ex);\n"
                + "        } finally {\n"
                + "            ConnectionPool.getConnectionPool().checkIn(dbConnection);\n"
                + "        }\n"
                + "        return result;\n"
                + "    }\n"
                + "    \n"
                + "    public boolean removeSLQ(String prepareSQL) {\n"
                + "        return removeSQL(prepareSQL, new Object[]{});\n"
                + "    }\n"
                + "    \n"
                + "    public boolean removeSQL(String prepareSQL, Object... parameter) {\n"
                + "        boolean result = false;\n"
                + "        Connection dbConnection = null;\n"
                + "        try {\n"
                + "            if (prepareSQL == null) {\n"
                + "                return result;\n"
                + "            }\n"
                + "\n"
                + "            PreparedStatement preparedStatement = null;\n"
                + "            System.out.println(\"query: \" + prepareSQL + \" \" + Arrays.asList(parameter));           \n"
                + "            dbConnection = ConnectionPool.getConnectionPool().checkOut();\n"
                + "            preparedStatement = dbConnection.prepareStatement(prepareSQL);\n"
                + "             \n"
                + "            for (int i = 0; i < parameter.length; i++) {\n"
                + "                preparedStatement.setObject(i + 1, parameter[i]);\n"
                + "            }\n"
                + "\n"
                + "            result = (preparedStatement.executeUpdate() > 0) ? true : false;\n"
                + "\n"
                + "        } catch (SecurityException | SQLException ex) {\n"
                + "            Logger.getLogger(DAOBase.class.getName()).log(Level.SEVERE, null, ex);\n"
                + "        } finally {\n"
                + "            ConnectionPool.getConnectionPool().checkIn(dbConnection);\n"
                + "        }\n"
                + "        return result;\n"
                + "    }\n"
                + "\n"
                + "    @Override\n"
                + "    public boolean save(T t) {\n"
                + "        boolean result = false;\n"
                + "        Connection dbConnection = null;\n"
                + "        try {\n"
                + "\n"
                + "            PreparedStatement preparedStatement = null;\n"
                + "            dbConnection = ConnectionPool.getConnectionPool().checkOut();\n"
                + "            preparedStatement = dbConnection.prepareStatement(prepareStatmentQuery(t));\n"
                + "\n"
                + "            String fields[] = getColumns();\n"
                + "            int num = fields.length;\n"
                + "\n"
                + "            for (int i = 0; i < num; i++) {\n"
                + "                Method prepareM = preparedStatement.getClass().getMethod(preparedStatementMethodsName[i], int.class, preparedStatementMethodsType[i]);\n"
                + "                prepareM.invoke(preparedStatement, (i + 1), getters[i].invoke(t));\n"
                + "            }\n"
                + "\n"
                + "            result = (preparedStatement.executeUpdate() > 0) ? true : false;\n"
                + "\n"
                + "        } catch (Exception ex) {\n"
                + "            Logger.getLogger(DAOBase.class.getName()).log(Level.SEVERE, null, ex);\n"
                + "        } finally {\n"
                + "            ConnectionPool.getConnectionPool().checkIn(dbConnection);\n"
                + "        }\n"
                + "        return result;\n"
                + "    }\n"
                + "\n"
                + "    @Override\n"
                + "    public boolean save(List<T> values) {\n"
                + "        boolean result = false;\n"
                + "        Connection dbConnection = null;\n"
                + "        try {\n"
                + "            String fields[] = getColumns();\n"
                + "            int num = fields.length;\n"
                + "            PreparedStatement preparedStatement = null;\n"
                + "            dbConnection = ConnectionPool.getConnectionPool().checkOut();\n"
                + "            preparedStatement = dbConnection.prepareStatement(prepareStatmentQuery(values.get(0)));\n"
                + "            dbConnection.setAutoCommit(false);\n"
                + "            for (T t : values) {\n"
                + "                for (int i = 0; i < num; i++) {\n"
                + "                    Method prepareM = preparedStatement.getClass().getMethod(preparedStatementMethodsName[i], int.class, preparedStatementMethodsType[i]);\n"
                + "                    prepareM.invoke(preparedStatement, (i + 1), getters[i].invoke(t));\n"
                + "                }\n"
                + "                preparedStatement.addBatch();\n"
                + "            }\n"
                + "            preparedStatement.executeBatch();\n"
                + "            dbConnection.commit();\n"
                + "            dbConnection.setAutoCommit(true);\n"
                + "\n"
                + "        } catch (Exception ex) {\n"
                + "            try {\n"
                + "                dbConnection.rollback();\n"
                + "                Logger.getLogger(DAOBase.class.getName()).log(Level.SEVERE, null, ex);\n"
                + "            } catch (SQLException ex1) {\n"
                + "                Logger.getLogger(DAOBase.class.getName()).log(Level.SEVERE, null, ex1);\n"
                + "            }\n"
                + "        } finally {\n"
                + "            ConnectionPool.getConnectionPool().checkIn(dbConnection);\n"
                + "        }\n"
                + "\n"
                + "        return result;\n"
                + "    }\n"
                + "\n"
                + "    @Override\n"
                + "    public boolean update(T t) {\n"
                + "        boolean result = false;\n"
                + "        Connection dbConnection = null;\n"
                + "        try {\n"
                + "\n"
                + "            PreparedStatement preparedStatement = null;\n"
                + "            dbConnection = ConnectionPool.getConnectionPool().checkOut();\n"
                + "            preparedStatement = dbConnection.prepareStatement(prepareStatmentQueryUpdate(t));\n"
                + "            String fields[] = getColumns();\n"
                + "            int num = fields.length;\n"
                + "\n"
                + "            for (int i = 0; i < num; i++) {\n"
                + "                Method prepareM = preparedStatement.getClass().getMethod(preparedStatementMethodsName[i], int.class, preparedStatementMethodsType[i]);\n"
                + "                prepareM.invoke(preparedStatement, (i + 1), getters[i].invoke(t));\n"
                + "            }\n"
                + "            \n"
                + "            String keys[] = getPrimaryKeyName();\n"
                + "            int key = keys.length;\n"
                + "            \n"
                + "            // find primary key\n"
                + "            for (int j = 0; j < key; j++) {\n"
                + "                Method prepareM = preparedStatement.getClass().getMethod(preparedPrimaryStatementMethodsName[j], int.class, preparedPrimaryStatementMethodsType[j]);\n"
                + "                prepareM.invoke(preparedStatement, (num + j + 1), preparedPrimaryStatment[j].invoke(t));\n"
                + "            }\n"
                + "\n"
                + "            result = (preparedStatement.executeUpdate() > 0) ? true : false;\n"
                + "\n"
                + "        } catch (Exception ex) {\n"
                + "            Logger.getLogger(DAOBase.class.getName()).log(Level.SEVERE, null, ex);\n"
                + "        } finally {\n"
                + "            ConnectionPool.getConnectionPool().checkIn(dbConnection);\n"
                + "        }\n"
                + "        return result;\n"
                + "    }\n"
                + "\n"
                + "    @Override\n"
                + "    public List<T> query(String prepareSQL) {\n"
                + "        return query(prepareSQL, new Object[]{});\n"
                + "    }\n"
                + "\n"
                + "    @Override\n"
                + "    public List<T> query(String prepareSQL, Object... parameter) {\n"
                + "\n"
                + "        List<T> items = new ArrayList<T>();\n"
                + "        Connection dbConnection = null;\n"
                + "        try {\n"
                + "\n"
                + "            PreparedStatement preparedStatement = null;\n"
                + "            System.out.println(\"query: \" + prepareSQL + \" \" + Arrays.asList(parameter));\n"
                + "            dbConnection = ConnectionPool.getConnectionPool().checkOut();\n"
                + "            preparedStatement = dbConnection.prepareStatement(prepareSQL);\n"
                + "\n"
                + "            for (int i = 0; i < parameter.length; i++) {\n"
                + "                preparedStatement.setObject(i + 1, parameter[i]);\n"
                + "            }\n"
                + "\n"
                + "            ResultSet res = preparedStatement.executeQuery();\n"
                + "\n"
                + "            String[] columns = getColumns();\n"
                + "            int num = columns.length;\n"
                + "\n"
                + "            while (res.next()) {\n"
                + "                Object object = persistentClass.newInstance();\n"
                + "                for (int i = 0; i < num; i++) {\n"
                + "                    setters[i].invoke(object, getMapperDB(methodsTypeSimpleName[i], res, columns[i]));\n"
                + "                }\n"
                + "                items.add((T) object);\n"
                + "            }\n"
                + "\n"
                + "            System.out.println(\"num of items: \" + items.size());\n"
                + "            res.close();\n"
                + "            preparedStatement.close();\n"
                + "\n"
                + "        } catch (Exception ex) {\n"
                + "            Logger.getLogger(DAOBase.class.getName()).log(Level.SEVERE, null, ex);\n"
                + "        } finally {\n"
                + "            ConnectionPool.getConnectionPool().checkIn(dbConnection);\n"
                + "        }\n"
                + "\n"
                + "        return items;\n"
                + "    }\n"
                + "    \n"
                + "     /**\n"
                + "     *\n"
                + "     * @param prepareSQL\n"
                + "     * @return\n"
                + "     */\n"
                + "    @Override\n"
                + "    public ResultSet selectResultSet(String prepareSQL){\n"
                + "        return selectResultSet(prepareSQL, new Object[]{});\n"
                + "    }\n"
                + "    \n"
                + "    /**\n"
                + "     *\n"
                + "     * @param prepareSQL\n"
                + "     * @param parameter\n"
                + "     * @return\n"
                + "     */\n"
                + "    @Override\n"
                + "    public ResultSet selectResultSet(String prepareSQL, Object... parameter){\n"
                + "    \n"
                + "        ResultSet res = null;\n"
                + "        Connection dbConnection = null;\n"
                + "        \n"
                + "        try {\n"
                + "            \n"
                + "            PreparedStatement preparedStatement = null;\n"
                + "            System.out.println(\"query: \" + prepareSQL + \" \" + Arrays.asList(parameter));           \n"
                + "            dbConnection = ConnectionPool.getConnectionPool().checkOut();\n"
                + "            preparedStatement = dbConnection.prepareStatement(prepareSQL);\n"
                + "             \n"
                + "            for (int i = 0; i < parameter.length; i++) {\n"
                + "                preparedStatement.setObject(i + 1, parameter[i]);\n"
                + "            }\n"
                + "            \n"
                + "            res = preparedStatement.executeQuery();\n"
                + "            \n"
                + "            //System.out.println(\"num of items: \" + res.getFetchSize());\n"
                + "            // do not close res and prepearedStatment\n"
                + "            // when return resultset\n"
                + "            //res.close();\n"
                + "            //preparedStatement.close();\n"
                + "            \n"
                + "        } catch (Exception ex) {\n"
                + "            Logger.getLogger(DAOBase.class.getName()).log(Level.SEVERE, null, ex);\n"
                + "        } finally {\n"
                + "            ConnectionPool.getConnectionPool().checkIn(dbConnection);\n"
                + "        }\n"
                + "\n"
                + "        return res;\n"
                + "    }\n"
                + "\n"
                + "    public int countRows() {\n"
                + "        \n"
                + "        int totalRows = 0;\n"
                + "\n"
                + "        Connection dbConnection = null;\n"
                + "        try {\n"
                + "\n"
                + "            PreparedStatement preparedStatement = null;\n"
                + "\n"
                + "            String query = \"SELECT COUNT(*) FROM \" + getTableName();\n"
                + "            //System.out.println(\"query: \" + query);           \n"
                + "            dbConnection = ConnectionPool.getConnectionPool().checkOut();\n"
                + "            preparedStatement = dbConnection.prepareStatement(query);\n"
                + "\n"
                + "            ResultSet res = preparedStatement.executeQuery();\n"
                + "            \n"
                + "            res.next();\n"
                + "            totalRows = res.getInt(1);\n"
                + "\n"
                + "            //System.out.println(\"num of items: \" + totalRows);\n"
                + "            res.close();\n"
                + "            preparedStatement.close();\n"
                + "\n"
                + "        } catch (Exception ex) {\n"
                + "            Logger.getLogger(DAOBase.class.getName()).log(Level.SEVERE, null, ex);\n"
                + "        } finally {\n"
                + "            ConnectionPool.getConnectionPool().checkIn(dbConnection);\n"
                + "        }\n"
                + "\n"
                + "        return totalRows;\n"
                + "        \n"
                + "    }\n"
                + "    \n"
                + "    @Override\n"
                + "    public T getLast() {\n"
                + "\n"
                + "        Connection dbConnection = null;\n"
                + "        try {\n"
                + "\n"
                + "            PreparedStatement preparedStatement = null;\n"
                + "\n"
                + "            int count = countRows();\n"
                + "            String query = \"SELECT * FROM \" + getTableName() + \" LIMIT \" + (count -1) + \" , \" + count;\n"
                + "//            System.out.println(\"query: \" + query);\n"
                + "            dbConnection = ConnectionPool.getConnectionPool().checkOut();\n"
                + "            preparedStatement = dbConnection.prepareStatement(query);\n"
                + "\n"
                + "            String fields[] = getColumns();\n"
                + "            int num = fields.length;\n"
                + "\n"
                + "            ResultSet res = preparedStatement.executeQuery();\n"
                + "            Object object = persistentClass.newInstance();\n"
                + "\n"
                + "            while (res.next()) {\n"
                + "                for (int i = 0; i < num; i++) {\n"
                + "                    setters[i].invoke(object, getMapperDB(methodsTypeSimpleName[i], res, fields[i]));\n"
                + "                }\n"
                + "                break;\n"
                + "            }\n"
                + "            //System.out.println(\"\" + object);\n"
                + "            return (T) object;\n"
                + "\n"
                + "        } catch (Exception ex) {\n"
                + "            Logger.getLogger(DAOBase.class.getName()).log(Level.SEVERE, null, ex);\n"
                + "            ex.printStackTrace();\n"
                + "        } finally {\n"
                + "            ConnectionPool.getConnectionPool().checkIn(dbConnection);\n"
                + "        }\n"
                + "\n"
                + "        return null;\n"
                + "    }\n"
                + "\n"
                + "    @Override\n"
                + "    public T getFirst() {\n"
                + "\n"
                + "        Connection dbConnection = null;\n"
                + "        try {\n"
                + "\n"
                + "            PreparedStatement preparedStatement = null;\n"
                + "\n"
                + "            String query = \"SELECT * FROM \" + getTableName() + \" LIMIT 1\";\n"
                + "//            System.out.println(\"query: \" + query);\n"
                + "            dbConnection = ConnectionPool.getConnectionPool().checkOut();\n"
                + "            preparedStatement = dbConnection.prepareStatement(query);\n"
                + "\n"
                + "            String fields[] = getColumns();\n"
                + "            int num = fields.length;\n"
                + "\n"
                + "            ResultSet res = preparedStatement.executeQuery();\n"
                + "            Object object = persistentClass.newInstance();\n"
                + "\n"
                + "            while (res.next()) {\n"
                + "                for (int i = 0; i < num; i++) {\n"
                + "                    setters[i].invoke(object, getMapperDB(methodsTypeSimpleName[i], res, fields[i]));\n"
                + "                }\n"
                + "                break;\n"
                + "            }\n"
                + "            //System.out.println(\"\" + object);\n"
                + "            return (T) object;\n"
                + "\n"
                + "        } catch (Exception ex) {\n"
                + "            Logger.getLogger(DAOBase.class.getName()).log(Level.SEVERE, null, ex);\n"
                + "            ex.printStackTrace();\n"
                + "        } finally {\n"
                + "            ConnectionPool.getConnectionPool().checkIn(dbConnection);\n"
                + "        }\n"
                + "\n"
                + "        return null;\n"
                + "    }\n"
                + "\n"
                + "    //==========================================================================\n"
                + "    // protected methods\n"
                + "    //==========================================================================\n"
                + "    protected String [] getPrimaryKeyName() {\n"
                + "        return null;\n"
                + "    }\n"
                + "\n"
                + "    protected String getTableName() {\n"
                + "        return null;\n"
                + "    }\n"
                + "\n"
                + "    protected String[] getColumns() {\n"
                + "        return null;\n"
                + "    }\n"
                + "\n"
                + "    protected Object getMapperDB(String type, ResultSet res, String columnName) throws SQLException {\n"
                + "\n"
                + "        if (type.equals(\"Short\") || type.equals(\"Short\")) {\n"
                + "            return res.getShort(columnName);\n"
                + "        } else if (type.equals(\"Integer\")) {\n"
                + "            return res.getInt(columnName);\n"
                + "        } else if (type.equals(\"Float\")) {\n"
                + "            return res.getFloat(columnName);\n"
                + "        } else if (type.equals(\"String\")) {\n"
                + "            return res.getString(columnName);\n"
                + "        } else if (type.equals(\"boolean\")) {\n"
                + "            return res.getBoolean(columnName);\n"
                + "        } else if (type.equals(\"Time\")) {\n"
                + "            return res.getTime(columnName);\n"
                + "        } else if (type.equals(\"Timestamp\")) {\n"
                + "            return res.getTimestamp(columnName);\n"
                + "        } else if (type.equals(\"Date\")) {\n"
                + "            return res.getDate(columnName);\n"
                + "        } else if (type.equals(\"Double\") || type.equals(\"double\")) {\n"
                + "            return res.getDouble(columnName);\n"
                + "        } else if (type.equals(\"BigDecimal\")) {\n"
                + "            return res.getBigDecimal(columnName);\n"
                + "        } else if (type.equals(\"Long\") || type.equals(\"long\")) {\n"
                + "            return res.getLong(columnName);\n"
                + "        } else if (type.equals(\"Blob\")) {\n"
                + "            return res.getBlob(columnName);\n"
                + "        } else if (type.equals(\"InputStream\")) {\n"
                + "            return res.getBinaryStream(columnName);\n"
                + "        } else if (type.equals(\"Byte\") || type.equals(\"byte\")) {\n"
                + "            return res.getByte(columnName);\n"
                + "        }\n"
                + "        return null;\n"
                + "    }\n"
                + "\n"
                + "    protected Class getChangeClass(String type) {\n"
                + "        \n"
                + "        if (type.equals(\"Short\") || type.equals(\"Short\")) {\n"
                + "            return short.class;\n"
                + "        } else if (type.equals(\"Integer\")) {\n"
                + "            return int.class;\n"
                + "        } else if (type.equals(\"Float\") || type.equals(\"float\")) {\n"
                + "            return float.class;\n"
                + "        } else if (type.equals(\"String\")) {\n"
                + "            return String.class;\n"
                + "        } else if (type.equals(\"boolean\") || type.equals(\"Boolean\")) {\n"
                + "            return boolean.class;\n"
                + "        } else if (type.equals(\"Time\")) {\n"
                + "            return Time.class;\n"
                + "        } else if (type.equals(\"Timestamp\")) {\n"
                + "            return Timestamp.class;\n"
                + "        } else if (type.equals(\"Date\")) {\n"
                + "            return Date.class;\n"
                + "        } else if (type.equals(\"Double\") || type.equals(\"double\")) {\n"
                + "            return double.class;\n"
                + "        } else if (type.equals(\"BigDecimal\")) {\n"
                + "            return BigDecimal.class;\n"
                + "        } else if (type.equals(\"Long\") || type.equals(\"long\")) {\n"
                + "            return long.class;\n"
                + "//        } else if (type.equals(\"Blob\") || type.equals(\"Short\")) {\n"
                + "//            return Blob;\n"
                + "        } else if (type.equals(\"InputStream\")) {\n"
                + "            return InputStream.class;\n"
                + "        } else if (type.equals(\"Byte\") || type.equals(\"byte\")) {\n"
                + "            return byte.class;\n"
                + "        }\n"
                + "        \n"
                + "        return null;\n"
                + "    }\n"
                + "\n"
                + "    protected String prepareStatmentQuery(T t) {\n"
                + "\n"
                + "        String insertValue = \"\";\n"
                + "        String insertColumn = \"\";\n"
                + "\n"
                + "        String fields[] = getColumns();\n"
                + "\n"
                + "        for (String field : fields) {\n"
                + "            insertValue += \"?,\";\n"
                + "            insertColumn += field + \", \";\n"
                + "        }\n"
                + "\n"
                + "        String insertQuery = \"INSERT INTO \" + getTableName() + \" (\" + insertColumn.substring(0, insertColumn.length() - 2) + \")\"\n"
                + "                + \" VALUES (\" + insertValue.substring(0, insertValue.length() - 1) + \")\";\n"
                + "//        System.out.println(\"insert preparestatment query: \" + insertQuery);\n"
                + "        return insertQuery;\n"
                + "    }\n"
                + "\n"
                + "    //==========================================================================\n"
                + "    // private methods\n"
                + "    //==========================================================================\n"
                + "    private void cashedMethods() {\n"
                + "\n"
                + "        String[] fields = getColumns();\n"
                + "\n"
                + "        setters = new Method[fields.length];\n"
                + "        getters = new Method[fields.length];\n"
                + "\n"
                + "        int num = fields.length;\n"
                + "\n"
                + "        for (int i = 0; i < num; i++) {\n"
                + "            try {\n"
                + "//                System.out.println(\"Found a method: \" + ClassGeneratorUtil.humanizeToGetter(fields[i]) + \n"
                + "//                        \" in class \" + ClassGeneratorUtil.humanize(getTableName()));\n"
                + "//                System.out.println(\"Found a method: \" + ClassGeneratorUtil.humanizeToSetter(fields[i]) + \n"
                + "//                        \" in class \" + ClassGeneratorUtil.humanize(getTableName()));\n"
                + "                Method mg = persistentClass.getMethod(ClassGeneratorUtil.humanizeToGetter(fields[i]), null);\n"
                + "                Method ms = persistentClass.getMethod(ClassGeneratorUtil.humanizeToSetter(fields[i]), this.methodsType[i]);\n"
                + "                getters[i] = mg;\n"
                + "                setters[i] = ms;\n"
                + "            } catch (NoSuchMethodException | SecurityException ex) {\n"
                + "                Logger.getLogger(DAOBase.class.getName()).log(Level.SEVERE, null, ex);\n"
                + "            }\n"
                + "        }\n"
                + "    }\n"
                + "\n"
                + "    private void cashedMethodsType() {\n"
                + "\n"
                + "        String[] fields = getColumns();\n"
                + "        this.methodsType = new Class[fields.length];\n"
                + "        this.methodsTypeSimpleName = new String[fields.length];\n"
                + "        \n"
                + "        int num = fields.length;\n"
                + "\n"
                + "        for (int i = 0; i < num; i++) {\n"
                + "            try {\n"
                + "                Method method = persistentClass.getMethod(ClassGeneratorUtil.humanizeToGetter(fields[i]), null);\n"
                + "                this.methodsType[i] = method.getReturnType();\n"
                + "                this.methodsTypeSimpleName[i] = method.getReturnType().getSimpleName();\n"
                + "//                System.out.println(\"Found a type: \" + ClassGeneratorUtil.humanizeToGetter(fields[i]) + \n"
                + "//                        \" in class \" + ClassGeneratorUtil.humanize(getTableName()));\n"
                + "            } catch (NoSuchMethodException | SecurityException ex) {\n"
                + "                Logger.getLogger(DAOBase.class.getName()).log(Level.SEVERE, null, ex);\n"
                + "            }\n"
                + "        }\n"
                + "        \n"
                + "        String[] keys = getPrimaryKeyName();\n"
                + "        int keysNum = keys.length;\n"
                + "        \n"
                + "        this.preparedPrimaryStatment = new Method[keysNum];\n"
                + "        \n"
                + "        for (int i = 0; i < keysNum; i++) {\n"
                + "            try {\n"
                + "                Method method = persistentClass.getMethod(ClassGeneratorUtil.humanizeToGetter(keys[i]), null);\n"
                + "                this.preparedPrimaryStatment[i] = method;\n"
                + "//                System.out.println(\"Found a type: \" + ClassGeneratorUtil.humanizeToGetter(fields[i]) + \n"
                + "//                        \" in class \" + ClassGeneratorUtil.humanize(getTableName()));\n"
                + "            } catch (NoSuchMethodException | SecurityException ex) {\n"
                + "                Logger.getLogger(DAOBase.class.getName()).log(Level.SEVERE, null, ex);\n"
                + "            }\n"
                + "        }    \n"
                + "\n"
                + "    }\n"
                + "\n"
                + "    private void cashedPreparedStatementMethodsName() {\n"
                + "\n"
                + "        String[] fields = getColumns();\n"
                + "        this.preparedStatementMethodsName = new String[fields.length];\n"
                + "        this.preparedStatementMethodsType = new Class[fields.length];\n"
                + "        int num = fields.length;\n"
                + "\n"
                + "        for (int i = 0; i < num; i++) {\n"
                + "            try {\n"
                + "                Class type = getChangeClass(methodsType[i].getSimpleName());\n"
                + "                this.preparedStatementMethodsName[i] = ClassGeneratorUtil.humanizeToSetter(type.getSimpleName());\n"
                + "                this.preparedStatementMethodsType[i] = type;\n"
                + "            } catch (Exception ex) {\n"
                + "                Logger.getLogger(DAOBase.class.getName()).log(Level.SEVERE, null, ex);\n"
                + "            }\n"
                + "        }\n"
                + "\n"
                + "    }\n"
                + "\n"
                + "    private void cashedPrimaryPreparedStatementMethodsName() {\n"
                + "\n"
                + "        String[] keys = getPrimaryKeyName();\n"
                + "        int num = keys.length;\n"
                + "        this.preparedPrimaryStatementMethodsName = new String[num];\n"
                + "        this.preparedPrimaryStatementMethodsType = new Class[num];\n"
                + "\n"
                + "        for (int i = 0; i < num; i++) {\n"
                + "            try {\n"
                + "                Method method = persistentClass.getMethod(ClassGeneratorUtil.humanizeToGetter(keys[i]), null);\n"
                + "                Class type = getChangeClass(method.getReturnType().getSimpleName());\n"
                + "                this.preparedPrimaryStatementMethodsName[i] = ClassGeneratorUtil.humanizeToSetter(type.getSimpleName());\n"
                + "                this.preparedPrimaryStatementMethodsType[i] = type;\n"
                + "            } catch (Exception ex) {\n"
                + "                Logger.getLogger(DAOBase.class.getName()).log(Level.SEVERE, null, ex);\n"
                + "            }\n"
                + "        }\n"
                + "\n"
                + "    }\n"
                + "     \n"
                + "    private String prepareStatmentQueryUpdate(T t) {\n"
                + "\n"
                + "        String fields[] = getColumns();\n"
                + "\n"
                + "        String update = \"UPDATE \" + getTableName() + \" SET \";\n"
                + "\n"
                + "        for (String field : fields) {\n"
                + "            update += (field + \"=?, \");\n"
                + "        }\n"
                + "\n"
                + "        update = update.substring(0, update.length() - 2) + \" WHERE \" + appendPrimaryKey();\n"
                + "        System.out.println(\"update preparestatment query: \" + update);\n"
                + "        return update;\n"
                + "    }\n"
                + "\n"
                + "    protected String appendPrimaryKey() {\n"
                + "        String rez = \"\";\n"
                + "        String[] keys = getPrimaryKeyName();\n"
                + "        for (String key : keys) {\n"
                + "            rez += key + \" = ? AND \";\n"
                + "        }\n"
                + "\n"
                + "        return rez.substring(0, rez.length() - 5);\n"
                + "    }\n";
        stringClass.append(daoClass);

    }

    @Override
    protected void generateFields() {
    }

    @Override
    protected void generateToString() {
    }

    @Override
    protected void generateHashCode() {
    }

    @Override
    protected void generateEquals() {
    }

    @Override
    protected void generateConstructor() {
    }

    @Override
    protected void generateGettersAndSetters() {
    }
}
